package killerqueen.game.xml.loader;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import killerqueen.game.interfaces.GameObject;
import killerqueen.game.xml.generated.Body;
import killerqueen.game.xml.generated.Level;
import killerqueen.game.xml.generated.Player;
import killerqueen.game.xml.generated.Parameter;

import org.apache.commons.beanutils.BeanUtils;
import org.jbox2d.dynamics.World;

public class XML2GameObjects {

  private List<GameObject> gameObjectList = new ArrayList<GameObject>();
  private GameObject player;

  // --------------------------------------------------------------------------------

  public void load(InputStream is, World world) {
    try {
      failsafeLoad(is, world);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  // --------------------------------------------------------------------------------

  private void failsafeLoad(InputStream is, World world) throws Exception {
    LevelLoader levelLoader = new LevelLoader();

    Level xmlLevel = levelLoader.load(is);

    this.player = createPlayer(world, xmlLevel.getPlayer());

    // ----------------------------------------

    for (Body body : xmlLevel.getBody()) {
      Class<?> clazz = Class.forName(body.getType());

      GameObject gameObject = (GameObject) clazz.newInstance();

      BeanUtils.populate(gameObject, createParameterMap(body.getParameter()));

      gameObject.init(world, body.getId());

      gameObjectList.add(gameObject);
    }
  }

  private GameObject createPlayer(World world, Player player) //
      throws Exception {

    Class<?> clazz = Class.forName(player.getType());
    GameObject gameObject = (GameObject) clazz.newInstance();

    Map<String, String> parameters = new HashMap<String, String>();
    parameters.put("x", Float.toString(player.getX()));
    parameters.put("y", Float.toString(player.getY()));

    BeanUtils.populate(gameObject, parameters);

    gameObject.init(world, "");

    return gameObject;
  }

  // --------------------------------------------------------------------------------

  private Map<String, String> createParameterMap(List<Parameter> parameterList) {
    Map<String, String> ret = new HashMap<String, String>();

    for (Parameter parameter : parameterList) {
      ret.put(parameter.getKey(), parameter.getVal());
    }

    return ret;
  }

  // --------------------------------------------------------------------------------

  public List<GameObject> getGameObjectList() {
    return gameObjectList;
  }

  public GameObject getPlayer() {
    return player;
  }
}
